package tgc.edu.ljc.service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.UUID;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import tgc.edu.ljc.custom.CommonService;
import tgc.edu.ljc.custom.CreateShortImage;
import tgc.edu.ljc.custom.TimeUtils;
import tgc.edu.ljc.entity.SysDept;
import tgc.edu.ljc.entity.SysFile;
import tgc.edu.ljc.entity.SysUser;
import tgc.edu.ljc.repository.SysFileRepositrory;
import tgc.edu.ljc.repository.SysUserRepository;
import tgc.edu.ljc.security.UserUtils;
import tgc.edu.ljc.web.form.SysFileForm;

@Service
public class SysFileService extends CommonService<SysFile, Integer> {

	@Value("${web.file-url}")
	public String url;
	@Autowired
	private SysFileRepositrory filedao;
	@Autowired
	private SysUserRepository userdao;
	@Autowired
	private DataSumService dsService;
	@Autowired
	private UserUtils userUtils;
	
	/***
	 * 保存文件 上传文件
	 * 
	 * @param file 文件流
	 * @return
	 * @throws IOException
	 */
	@Transactional
	public boolean savefile(SysFileForm fileform) {
		// 数据库文件保存
		SysFile fileEntity = new SysFile();
		BeanUtils.copyProperties(fileform, fileEntity, "id");
		String uuid = UUID.randomUUID().toString();
		MultipartFile file = fileform.getFile();
		String filename = file.getOriginalFilename();
		if(StringUtils.hasText(fileform.getFileName())) {
			filename=fileform.getFileName();
		}
		fileEntity.setFileName(filename);
		fileEntity.setFileUuid(uuid);
		fileEntity.setFileNature(dsService.findById(fileform.getFileNature()));
		String username = fileform.getFileUser();
		SysUser user;
		if(StringUtils.hasText(username)) {
			user=userdao.findByUsername(username);
			if(user!=null) {
				fileEntity.setUserDept(user.getDept());
				fileEntity.setUploadsUsername(username);
				fileEntity.setUploadsName(user.getName());
			}else {
				return false;
			}
		}else {
			user=userUtils.getUser();
			fileEntity.setUserDept(user.getDept());
			fileEntity.setUploadsUsername(user.getUsername());
			fileEntity.setUploadsName(user.getName());
		}
		/*try {
			// 上传文件的用户获取
			UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication()
					.getPrincipal();
			String user = userDetails.getUsername();
			SysUser sysUser = userdao.findByUsername(user);
			if (sysUser != null) {
				username = sysUser.getUsername();
				fileEntity.setUserDept(sysUser.getDept());
				fileEntity.setUploadsUsername(username);
				fileEntity.setUploadsName(sysUser.getName());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}*/
		
		fileEntity.setUpdateTime(TimeUtils.getStringDate());
		fileEntity.setFileType(dsService.findById(fileform.getFileType()));
		fileEntity.setFileSize(String.valueOf(file.getSize()));
		fileEntity.setIsUsed(true);
		String fileURL = url;
		String fileTypeUrl = fileform.getFileTypeUrl();
		fileEntity.setFileTypeUrl(fileTypeUrl);
		if (fileTypeUrl != null && fileTypeUrl != "") {
			fileURL += "\\" + fileTypeUrl;
		}
		// 文件保存到本地
		File path = found(fileURL);// 找到 指定文件夹
		if(!path.exists()) {
			path.mkdir();
		}
		String shortImageURL=url+"\\shortImage\\";
		File shortImageFile=new File(shortImageURL);
		if(!shortImageFile.exists()) {
			shortImageFile.mkdir();
		}
		
		File saveFile = new File(path, uuid);
		try {
			filedao.save(fileEntity);
			file.transferTo(saveFile);
			//如果是图片，则生成缩略图 
			if("DICT_FILETYPE_PICTURE".equals(fileEntity.getFileType().getCode())) {
				CreateShortImage.createThumbnail(path+"\\"+uuid, shortImageURL+uuid, 400, 300);
			}
			//如果是视频，则调用d:盘的ffmpeg生成视频的缩略图
			if("DICT_FILETYPE_VIDEO".equals(fileEntity.getFileType().getCode())) {
				String videoRealPath = path+"\\"+uuid;
				String imageRealPath =shortImageURL+uuid+".png";
				try {
					Runtime.getRuntime().exec("D:\\ffmpeg\\ffmpeg.bat " + videoRealPath + " " + imageRealPath);
					//Runtime.getRuntime().exec("exit");
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
			}
			return true;
		} catch (IllegalStateException | IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	/***
	 * 文件下载
	 * 
	 * @param uuid     文件的UUID
	 * @param request
	 * @param response
	 */
	public Boolean download(String uuid, HttpServletRequest request, HttpServletResponse response) {
		SysFile sysfile = filedao.findByFileUuid(uuid);
		if (sysfile != null) {
			String filename = sysfile.getFileName();
			filename = getStr(request, filename);
			String fileURL = url;
			String fileTypeUrl = sysfile.getFileTypeUrl();
			if (fileTypeUrl != null && fileTypeUrl != "") {
				fileURL += "\\" + fileTypeUrl;
			}
			File file = new File(fileURL, uuid);
			if (file.exists()) {
				FileInputStream fis;
				try {
					fis = new FileInputStream(file);
					response.setContentType("application/x-msdownload");
					response.addHeader("Access-Control-Allow-Origin", "*");
					response.addHeader("Content-Disposition", "attachment; filename=" + filename);
					ServletOutputStream out = response.getOutputStream();
					byte[] buf = new byte[20480];
					int n = 0;
					while ((n = fis.read(buf)) != -1) {
						out.write(buf, 0, n);
					}
					fis.close();
					out.flush();
					out.close();
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				return true;
			}
		}
		return false;

	}

	/****
	 * 处理火狐下载乱码问题
	 * 
	 * @param request
	 * @param fileName
	 * @return
	 */
	private String getStr(HttpServletRequest request, String fileName) {
		String downloadFileName = null;
		// 仅提供了部分代码，因为我们已经明确问题的所在，知道修改那一部分了，（代码中downloadFileName 即代表
		// *=utf-8'zh_cn'文件名.xx部分）
		String agent = request.getHeader("USER-AGENT");
		try {
			if (agent != null && agent.toLowerCase().indexOf("firefox") > 0) {
				// downloadFileName = "=?UTF-8?B?" + (new
				// String(Base64Utils.encode(fileName.getBytes("UTF-8")))) + "?=";
				// 设置字符集
				downloadFileName = "=?UTF-8?B?" + Base64Utils.encodeToString(fileName.getBytes("UTF-8")) + "?=";
			} else {
				downloadFileName = java.net.URLEncoder.encode(fileName, "UTF-8");
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return downloadFileName;
	}

	/****
	 * 分配文件储存地区
	 * 
	 * @param string
	 * @param string
	 * @return
	 */
	private File found(String fileURL) {
		File pat = new File(fileURL);
		if (!pat.isDirectory()) {
			pat.mkdirs();
		}
		return pat;
	}
	
	@Transactional
	public Boolean deleteFile(Integer id) {
		SysFile findById = this.findById(id);
		String code = findById.getFileType().getCode();
		String FileURL = this.url;
		String TypeURL = findById.getFileTypeUrl();
		if (TypeURL == null || TypeURL == "") {
			FileURL += "\\" + findById.getFileUuid();
		} else {
			FileURL += "\\" + TypeURL + "\\" + findById.getFileUuid();
		}
		File file = new File(FileURL);
		if (file.exists() && file.isFile()) {
			//如果是图片或视频文件，先删除缩略图
			if("DICT_FILETYPE_PICTURE".equals(code.trim())||"DICT_FILETYPE_VIDEO".equals(code.trim())) {
				File shortImage=new File(this.url+"\\shortImage", findById.getFileUuid()+".png");
				if(shortImage.delete()) {
					System.out.println(shortImage.getAbsolutePath()+"删除成功");
				}else {
					System.out.println(shortImage.getAbsolutePath()+"删除失败");
				}
			}
			if (file.delete()) {
				System.out.println(TimeUtils.getStringDate() + " 删除文件" + FileURL + "成功！");
			} else {
				System.out.println(TimeUtils.getStringDate() + "删除文件" + FileURL + "失败！");
			}
		} else {
			System.out.println(TimeUtils.getStringDate() + "删除文件失败：" + FileURL + "不存在！");
		}
		this.delete(findById);
		return true;
	}
	
	@Transactional
	public void mySave(SysFile model, SysFileForm form) {
		
		model.setFileTitle(form.getFileTitle());
		model.setFileNature(dsService.findById(form.getFileNature()));
		model.setFileType(dsService.findById(form.getFileType()));
		model.setFileRemark(form.getFileRemark());
		if(form.getFile()==null||!StringUtils.hasText( form.getFile().getOriginalFilename())) {
			this.save(model);
			String uuid = model.getFileUuid();
			String shortImageURL=url+"\\shortImage\\";
			//如果是图片，则生成缩略图 
			if("DICT_FILETYPE_PICTURE".equals(model.getFileType().getCode())) {
				CreateShortImage.createThumbnail(url+"\\"+uuid, shortImageURL+uuid, 400, 300);
			}
			//如果是视频，则调用d:盘的ffmpeg生成视频的缩略图
			if("DICT_FILETYPE_VIDEO".equals(model.getFileType().getCode())) {
				String videoRealPath = url+"\\"+uuid;
				String imageRealPath =shortImageURL+uuid+".png";
				try {
					Runtime.getRuntime().exec("D:\\ffmpeg\\ffmpeg.bat " + videoRealPath + " " + imageRealPath);
					//Runtime.getRuntime().exec("exit");
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
			}
		}else {
			MultipartFile file = form.getFile();
			String filename = file.getOriginalFilename();
			model.setFileName(filename);
			model.setFileSize(file.getSize()+"");
			String fileUuid = model.getFileUuid();
			new File(url, fileUuid).delete();  //删除掉以前的文件
			 String newFileUuid = UUID.randomUUID().toString();
			model.setFileUuid(newFileUuid);
			this.save(model);
			try {
				file.transferTo(new File(url,model.getFileUuid()));
				String path=url+"\\shortImage";
				File parent=new File(path);
				if(!parent.exists()) {
					parent.mkdir();
				}
				//如以前有缩略图，则删除
				File file2 = new File(parent, fileUuid+".png");
				if(file2.exists()) {
					file2.delete();
				}
				String uuid = model.getFileUuid();
				String shortImageURL=url+"\\shortImage\\";
				//如果是图片，则生成缩略图 
				if("DICT_FILETYPE_PICTURE".equals(model.getFileType().getCode())) {
					CreateShortImage.createThumbnail(url+"\\"+uuid, shortImageURL+uuid, 400, 300);
				}
				//如果是视频，则调用d:盘的ffmpeg生成视频的缩略图
				if("DICT_FILETYPE_VIDEO".equals(model.getFileType().getCode())) {
					String videoRealPath = url+"\\"+uuid;
					String imageRealPath =shortImageURL+uuid+".png";
					try {
						Runtime.getRuntime().exec("D:\\ffmpeg\\ffmpeg.bat " + videoRealPath + " " + imageRealPath);
						//Runtime.getRuntime().exec("exit");
					} catch (Exception e) {
						System.out.println(e.getMessage());
					}
				}
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
	}

	/***
	 * 查询当前用户的所在部门和下级部门
	 * @param dept当前用户部门
	 * @return
	 */
	public List<SysDept> setSysDepts(SysDept dept ,List<SysDept> list) {
		list.add(dept);
		List<SysDept> sysDpets = dept.getChildren();
		for (SysDept sysDept : sysDpets) {
			setSysDepts(sysDept,list);
		}
		return list;
	}
	
	/***
	 * 下载缩略图
	 * @param uuid 
	 * @param response
	 * @return 成功与否
	 */
	public Boolean downloadShortImage(String uuid,HttpServletResponse response) {
		String path=url+"\\shortImage";
		String filename=uuid+".png";
		File file=new File(path, filename);
		if(file.exists()) {
			FileInputStream fis;
			try {
				fis=new FileInputStream(file);
				response.setContentType("application/x-msdownload");
				response.addHeader("Content-Disposition", "attachment; filename=" + filename);
				ServletOutputStream out = response.getOutputStream();
				byte[] buf = new byte[2048];
				int n = 0;
				while ((n = fis.read(buf)) != -1) {
					out.write(buf, 0, n);
				}
				fis.close();
				out.flush();
				out.close();
				return true;
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		return false;
	}
	
	public SysFile findByFileUuid(String uuid) {
		return filedao.findByFileUuid(uuid);
	}

}
